Skip to content

Conversation

@Aaron1011
Copy link
Member

@Aaron1011 Aaron1011 commented Jan 26, 2026

This should result in Sentry displaying a link from the task execution trace (where 'await_event' is called) back to the trace that performed the 'emit_event' call

Note that this is a breaking change, as we now wrap the user's payload in a struct when reading/writing to the database. Going forward, we'll be able to add new (optional) fields to this wrapper struct without breaking existing durable deployments


Note

High Risk
High risk because it introduces a breaking change to the persisted event payload JSON format and adds DB-side validation, impacting all producers/consumers of emit_event/await_event and internal child completion events.

Overview
All durable events are now persisted and transported as a structured wrapper DurableEventPayload with { inner, metadata } instead of storing the user payload directly.

Durable::emit_event/emit_event_with now wraps the user payload into inner and (when telemetry is enabled) injects trace context into metadata, while TaskContext::await_event/join unwrap inner and optionally link spans using the extracted metadata.

Postgres functions are updated via a new migration (and schema.sql) to enforce the wrapper shape in durable.emit_event and to emit child completion events using the new wrapper format; tests that call SQL emit_event directly are updated accordingly.

Written by Cursor Bugbot for commit 8ac0de2. This will update automatically on new commits. Configure here.

This should result in Sentry displaying a link from the task
execution trace (where 'await_event' is called) back to the trace
that performed the 'emit_event' call

Note that this is a *breaking change*, as we now wrap the user's payload
in a struct when reading/writing to the database. Going forward, we'll
be able to add new (optional) fields to this wrapper struct without
breaking existing durable deployments
@Aaron1011
Copy link
Member Author

@virajmehta I opted to always store a json object that looks like {"inner": <obj>, "metadata": <object>}, including for the built-in durable events. This was much simpler than modifying all of the locking code to handle multiple columns.

@virajmehta
Copy link
Member

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ec45961deb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@virajmehta virajmehta enabled auto-merge January 29, 2026 17:30
@virajmehta virajmehta added this pull request to the merge queue Jan 29, 2026
Merged via the queue into main with commit 3eb3259 Jan 29, 2026
2 checks passed
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

if not p_payload ? 'metadata' then
raise exception 'p_payload must contain a ''metadata'' key';
end if;
end if;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SQL validation allows non-object payloads causing Rust errors

Low Severity

The SQL validation in emit_event only validates payloads when jsonb_typeof(p_payload) = 'object'. Non-object JSON values (strings, numbers, arrays, booleans) bypass validation entirely but will cause deserialization failures in Rust, since AwaitEventResult.payload expects a DurableEventPayload structure. The reviewer requested to "enforce that exactly these two keys are present" which implies non-conforming payloads should be rejected, not silently allowed. Direct SQL calls with non-object payloads would store invalid data.

Additional Locations (1)

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants